#define _CRT_SECURE_NO_WARNINGS 1

// assert断言
// assert()接受一个表达式作为参数，若为真，则没有作用
// 如果已经确认程序没问题，不需要断言
// 那么就在assert.h头文件前面加一个宏定义
// #define NDEBUG
//#include <stdio.h>
//#include <assert.h>
//
//int main()
//{
//	int a = 10;
//	int* p = &a;
//	// ...
//	// ...
//	p = NULL;
//	// ...
//	// ...
//	assert(p != NULL);
//
//	return 0;
//}

//// 指针的使用和传址调用
//// 所谓传址调用，就是函数在调用的本身
//#include <string.h>
//// size_t == unsigned int
//size_t my_strlen(const char* str)
//{
//	size_t count = 0;
//	assert(str != NULL);
//	while (*str != '\0') {
//		count++;
//		str++;
//	}
//	return count;
//}
//
//int main()
//{
//	char arr[] = "abcdef";
//	size_t len = my_strlen(arr); // 数组名是数组首元素的地址
//
//	printf("%zd\n", len);
//
//	return 0;
//}

// 传值调用和传址调用
// 传值调用函数时候，函数的实参给形参时，形参是实参的一份临时拷贝
// 形参有自己的独立空间
// 因此，对形参的修改不会影响实参
//#include <stdio.h>
//
//void swap(int x, int y)
//{
//	int z = 0;
//	z = x;
//	x = y;
//	y = z;
//}
//
//int main()
//{
//	int a, b;
//	scanf("%d %d", &a, &b);
//
//	printf("交换前：%d %d\n", a, b);
//	swap(a, b);
//	printf("交换后：%d %d\n", a, b);
//
//	return 0;
//}

// 传址调用，能让函数和主函数之间建立真正的联系
// 在函数内部修改主调函数的变量
// 所以要根据实际情况来决定传值调用和传址调用


// 数组名是数组首元素的地址，但是
// 1.sizeof内部单独放一个数组名的时候，数组名表示整个数组，计算的是整个数组的大小，单位是字节
// 2.&数组名，数组名表示的是整个数组，取出的是整个数组的地址
//#include <stdio.h>
//
//int main()
//{
//	int arr[10] = { 0 };
//	
//	printf("%p\n", arr);
//	printf("%p\n", &arr[0]);
//	printf("%zd\n", sizeof(arr));
//	printf("%p\n", &arr);
//
//	return 0;
//}

//#include <stdio.h>
//
//int main()
//{
//	int arr[10] = { 0 };
//
//	printf("%p\n", &arr[0]); // int*
//	printf("%p\n", &arr[0] + 1); // +4
//
//	printf("%p\n", arr); // int*
//	printf("%p\n", arr + 1); // +4
//
//	printf("%p\n", &arr);
//	printf("%p\n", &arr + 1); // +40
//
//	return 0;
//}

//#include <stdio.h>
//
//int main()
//{
//	// 因为数组在内存中是连续存放的
//	// 数组名就是首元素的地址
//
//	int arr[10] = { 0 };
//	int sz = sizeof(arr) / sizeof(arr[0]);
//	int* p = arr;
//
//	for (int i = 0; i < sz; i++) {
//		scanf("%d", p + i);
//	}
//
//	for (int i = 0; i < sz; i++) {
//		printf("%d ", *(p + i));
//		/*printf("%d ", i[arr]);*/
//
//		// printf("%d ", arr[i]);
//		// printf("%d ", *(p + i));
//		// printf("%d ", *(arr + i));
//		
//		// 编译器都是化为*(i + arr) 或者 *(arr + i)
//		// arr[i] == *(arr + i)
//		// *(i + arr) == i[arr]
//		// p[i] == *(p + i)
//	}
//
//	return 0;
//}

// 数组的底层本质就是指针
//#include <stdio.h>
//
//void test(int arr[]) // int* arr
//{
//	// 数组传参的时候，传递的并非是数组
//	int sz = sizeof(arr) / sizeof(arr[0]);
//	printf("%d\n", sz);
//}
//
//void Print(int* arr, int sz)
//{
//	for (int i = 0; i < sz; i++) {
//		printf("%d ", arr[i]);
//	}
//}
//
//int main()
//{
//	// 一维数组传参的本质
//	int arr[10] = { 0 };
//	int sz = sizeof(arr) / sizeof(arr[0]);
//
//
//	test(arr); // 这里的数组名就是数组首元素的地址
//	Print(arr, sz);
//
//	return 0;
//}


// BubbleSort
//#include <stdio.h>
//
//int count = 0;
//int main()
//{
//	int arr[10] = { 1,5,8,9,4,2,3,7,5,10 };
//	int sz = sizeof(arr) / sizeof(arr[0]);
//
//	for (int i = 1; i < sz; i++) {
//		int flag = 1; // 假设有序
//		for (int j = sz - 1; j > 0 ; j--) {
//			count++;
//			if (arr[j] < arr[j - 1]) {
//				int tmp = arr[j];
//				arr[j] = arr[j - 1];
//				arr[j - 1] = tmp;
//				flag = 0; //
//			}
//		}
//		// 注释掉count，比较切断与不切断两者的效率差别
//		if (flag == 1) break;
//	}
//
//	for (int i = 0; i < sz; i++) {
//		printf("%d ", arr[i]);
//	}
//	printf("\n%d\n", count);
//
//	return 0;
//}

































































